package com.hzw.saas.web.admin.email.controller;

import java.util.Objects;
import javax.annotation.Resource;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.hzw.saas.api.email.IEmailLogService;
import com.hzw.saas.api.email.bo.EmailLogBO;
import com.hzw.saas.api.email.bo.EmailLogBriefBO;
import com.hzw.saas.api.email.query.EmailLogAddQuery;
import com.hzw.saas.api.email.query.EmailLogSendQuery;
import com.hzw.saas.api.email.query.EmailLogUpdateQuery;
import com.hzw.saas.api.rbac.constants.SaasAuth;
import com.hzw.saas.common.config.annotation.SysLog;
import com.hzw.saas.common.config.exception.DefaultSaasException;
import com.hzw.saas.common.config.util.AssertUtil;
import com.hzw.saas.common.config.util.PageParam;
import com.hzw.saas.common.security.utils.SecurityUtils;
import com.hzw.saas.common.util.exception.ConflictException;
import com.hzw.saas.service.rbac.config.RbacConfig;
import com.hzw.saas.web.admin.email.params.IdsParam;
import com.hzw.saas.web.admin.email.params.ResendEmailParam;
import com.hzw.saas.web.admin.security.PermissionService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author zzl
 * @since 09/09/2021
 */
@RestController
@RequiredArgsConstructor
@Slf4j
@Api(tags = "邮件管理")
public class EmailController {

    @Resource(name = PermissionService.BEAN_NAME)
    private PermissionService permissionService;
    @Resource(name = SaasAuth.BEAN_NAME)
    private SaasAuth saasAuth;

    private final RbacConfig rbacConfig;
    private final IEmailLogService emailLogService;

    @GetMapping("/sys/emails/page")
    @SysLog
    @ApiOperation(value = "分页获取邮件列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "type", value = "邮件类型", dataType = "int", paramType = "query"),
        @ApiImplicitParam(name = "status", value = "邮件状态, 0:草稿，1:发送成功，-1:发送失败", dataType = "int", paramType = "query"),
        @ApiImplicitParam(name = "fuzzy", value = "模糊检索参数", dataType = "String", paramType = "query"),
    })
    @ApiOperationSort(11)
    public ResponseEntity<IPage<EmailLogBriefBO>> pageEmails(PageParam pageParam, Integer type, Integer status, String fuzzy) {
        boolean queryAll = permissionService.hasAny(saasAuth.EMAIL_LIST_ALL);
        boolean querySelf = permissionService.hasAny(saasAuth.EMAIL_LIST);
        String creatorId;
        if (queryAll) {
            creatorId = null;
        } else if (querySelf) {
            creatorId = SecurityUtils.getUser().getUserId();
        } else {
            throw DefaultSaasException.build("无权限").status(HttpStatus.FORBIDDEN);
        }
        IPage<EmailLogBriefBO> page = emailLogService.pageEmailBrief(pageParam, creatorId, type, status, fuzzy);
        return ResponseEntity.ok(page);
    }

    @GetMapping("/sys/email/{pid}")
    @SysLog
    @ApiOperation(value = "获取邮件详情")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "pid", value = "邮件ID", dataType = "String", paramType = "path", required = true),
    })
    @ApiOperationSort(12)
    public ResponseEntity<EmailLogBO> getEmail(@PathVariable String pid) {
        EmailLogBO email = emailLogService.getEmail(pid);
        AssertUtil.assertThrow("邮件未找到", Objects.isNull(email));
        return ResponseEntity.ok(email);
    }

    @PostMapping("/sys/email/draft")
    @SysLog(operation = "保存邮件草稿", mode = 3)
    @ApiOperation(value = "保存邮件草稿")
    @ApiOperationSort(13)
    public ResponseEntity<Void> saveEmailDraft(@RequestBody EmailLogAddQuery query) {
        String userId = SecurityUtils.getUser().getUserId();
        // 设置发件人
        query.setFrom(userId);
        emailLogService.saveDraft(query);
        return ResponseEntity.ok().build();
    }

    @PutMapping("/sys/email/draft")
    @SysLog(operation = "更新邮件草稿", mode = 3)
    @ApiOperation(value = "更新邮件草稿")
    @ApiOperationSort(14)
    public ResponseEntity<Void> updateEmailDraft(@RequestBody EmailLogUpdateQuery query) {
        String userId = SecurityUtils.getUser().getUserId();
        // 设置发件人
        query.setFrom(userId);
        boolean update = emailLogService.updateDraft(query);
        AssertUtil.assertThrow("更新失败！请稍后重试", !update);
        return ResponseEntity.ok().build();
    }

    @PostMapping("/sys/email")
    @SysLog(operation = "发送邮件", mode = 3)
    @ApiOperation(value = "发送邮件", notes = "发送邮件，该接口可能调用时间较长，请考虑设置界面等待动画")
    @ApiOperationSort(15)
    public ResponseEntity<Void> sendEmail(@Validated @RequestBody EmailLogSendQuery query) {
        String userId = SecurityUtils.getUser().getUserId();
        // 设置发件人
        query.setFrom(userId);
        boolean result = emailLogService.sendEmail(query);
        AssertUtil.assertThrow("邮件发送失败", !result);
        return ResponseEntity.ok().build();
    }

    @PutMapping("/sys/email")
    @SysLog(operation = "重新发送邮件", mode = 3)
    @ApiOperation(value = "重新发送邮件", notes = "重新发送邮件，已失败邮件直接重新发送，已发送成功的邮件需加上force=true参数，否则会返回409错误")
    @ApiResponses({
        @ApiResponse(code = 200, message = "重新发送成功"),
        @ApiResponse(code = 400, message = "请求参数错误"),
        @ApiResponse(code = 409, message = "邮件已发送成功"),
    })
    @ApiOperationSort(16)
    public ResponseEntity<Void> resendEmail(@Validated @RequestBody ResendEmailParam param) throws ConflictException {
        emailLogService.resendEmail(param.getPid(), param.getForce());
        return ResponseEntity.ok().build();
    }

    @DeleteMapping("/sys/emails")
    @SysLog(operation = "批量删除邮件", mode = 3)
    @ApiOperation(value = "批量删除邮件")
    @ApiOperationSort(17)
    public ResponseEntity<Void> deleteEmails(@Validated @RequestBody IdsParam param) {
        boolean delete = emailLogService.deleteEmailLogs(param.getPids());
        AssertUtil.assertThrow("删除失败！请稍候重试", !delete);
        return ResponseEntity.ok().build();
    }

}
